/*
Copyright 2025 The Kubernetes Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

	http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package kube

import (
	"testing"

	confv1beta1 "gopkg.openfuyao.cn/bkecommon/cluster/api/v1beta1"
	corev1 "k8s.io/api/core/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

	bkev1beta1 "gopkg.openfuyao.cn/cluster-api-provider-bke/api/v1beta1"
)

const (
	// testNodeSkipIP 测试中需要跳过的节点IP（使用本地回环地址用于测试）
	testNodeSkipIP = "127.0.0.100"
	// testNodeCheckIP 测试中需要检查的节点IP（使用本地回环地址用于测试）
	testNodeCheckIP = "127.0.0.101"
	// testClusterName 测试集群名称
	testClusterName = "test-cluster"
	// testNodeSkipName 需要跳过的节点名称
	testNodeSkipName = "node-skip"
	// testNodeCheckName 需要检查的节点名称
	testNodeCheckName = "node-check"
	// expectedNodeCount 期望的节点数量
	expectedNodeCount = 2
)

// createTestCluster 创建测试用的 BKECluster 对象
func createTestCluster() *bkev1beta1.BKECluster {
	return &bkev1beta1.BKECluster{
		ObjectMeta: metav1.ObjectMeta{
			Name: testClusterName,
		},
		Status: confv1beta1.BKEClusterStatus{
			NodesStatus: confv1beta1.NodesStates{
				{
					Node: confv1beta1.Node{
						IP:       testNodeSkipIP,
						Hostname: testNodeSkipName,
					},
					NeedSkip: true,
				},
				{
					Node: confv1beta1.Node{
						IP:       testNodeCheckIP,
						Hostname: testNodeCheckName,
					},
					NeedSkip: false,
				},
			},
		},
	}
}

// createTestNode 创建测试用的 Kubernetes Node 对象
func createTestNode(name, ip string) corev1.Node {
	return corev1.Node{
		ObjectMeta: metav1.ObjectMeta{
			Name: name,
		},
		Status: corev1.NodeStatus{
			Addresses: []corev1.NodeAddress{
				{
					Type:    corev1.NodeInternalIP,
					Address: ip,
				},
			},
			Conditions: []corev1.NodeCondition{
				{
					Type:   corev1.NodeReady,
					Status: corev1.ConditionTrue,
				},
			},
		},
	}
}

// createTestNodes 创建测试用的节点列表
func createTestNodes() []corev1.Node {
	return []corev1.Node{
		createTestNode(testNodeSkipName, testNodeSkipIP),
		createTestNode(testNodeCheckName, testNodeCheckIP),
	}
}

// verifyNodeSkipLogic 验证节点跳过逻辑
func verifyNodeSkipLogic(t *testing.T, cluster *bkev1beta1.BKECluster) {
	shouldSkipFirst := cluster.GetNodeStateNeedSkip(testNodeSkipIP)
	shouldSkipSecond := cluster.GetNodeStateNeedSkip(testNodeCheckIP)

	if !shouldSkipFirst {
		t.Errorf("Expected node %s to be skipped (needskip=true), "+
			"but GetNodeStateNeedSkip returned false", testNodeSkipIP)
	}

	if shouldSkipSecond {
		t.Errorf("Expected node %s not to be skipped (needskip=false), "+
			"but GetNodeStateNeedSkip returned true", testNodeCheckIP)
	}
}

// verifyNodeCount 验证节点数量
func verifyNodeCount(t *testing.T, nodes []corev1.Node) {
	if len(nodes) != expectedNodeCount {
		t.Errorf("Expected %d nodes in test data, but got %d", expectedNodeCount, len(nodes))
	}
}

// logTestCompletion 输出测试完成信息
func logTestCompletion(t *testing.T, cluster *bkev1beta1.BKECluster, nodes []corev1.Node) {
	t.Logf("Test completed: nodes=%d, cluster=%s", len(nodes), cluster.Name)
	t.Logf("Node %s (needskip=true) should be skipped", testNodeSkipIP)
	t.Logf("Node %s (needskip=false) should be checked", testNodeCheckIP)
	t.Logf("Skip logic uses GetNodeStateNeedSkip method in CheckClusterHealth")
}

// TestCheckClusterHealthWithSkip 测试 CheckClusterHealth 方法中的跳过逻辑
func TestCheckClusterHealthWithSkip(t *testing.T) {
	t.Run("nodes with needskip=true should be skipped in CheckClusterHealth", func(t *testing.T) {
		cluster := createTestCluster()
		nodes := createTestNodes()

		verifyNodeSkipLogic(t, cluster)
		verifyNodeCount(t, nodes)
		logTestCompletion(t, cluster, nodes)
	})
}
